import json
import time
from ftplib import FTP
from io import BytesIO

from flask import Flask, render_template, request, send_from_directory, abort, Config, send_file
import os
from flask_apscheduler import APScheduler

import db
from upload import scan_upload_files

scheduler = APScheduler()
app = Flask(__name__)
# ftp服务器文件根目录
ftp_root_path = '/myftp'
# 配置连接FTP的参数
ftp = FTP()
# 服务器IP和端口
ftp.connect("relosy.cn", 21)
ftp.encoding = "utf-8"
# 匿名登陆, 如果需要登陆, 就把两个空字符串写上用户名和密码就行了("username", "password")
ftp.login(user="root", passwd="Avenge1026")
ftp.set_pasv(True)

# 当前用户ID
cur_user_id = 1
cur_user_local_paths = []


def getfile():
    # print(os.getcwd().replace('\\', '/'))
    path1 = os.getcwd().replace('\\', '/') + '/upload_files'
    path2 = os.getcwd().replace('\\', '/')
    # 跳转目录 跳转到下载文件的目录，获得下载文件目录里面的list之后，然后再跳转出来
    # 这个跳转的步骤是为了获取到upload_files目录下的文件的名字，然后把它放进f_list中
    os.chdir(path1)
    f_list = os.listdir()
    os.chdir(path2)
    # print(os.getcwd().replace('\\', '/'))
    return f_list


def get_ftp_files(parent_path=''):
    # 获取ftp服务器上的文件
    global cur_user_id
    print("用户ID：" + str(cur_user_id))
    remote_path = ftp_root_path + '/' + 'user-' + str(cur_user_id) + '/' + parent_path
    try:
        ftp.cwd(remote_path)
    except Exception as e:
        ftp.mkd(remote_path)
    files = ftp.nlst()
    return files


def is_Have_file(filename):
    path1 = os.getcwd().replace('\\', '/') + '/upload_files'
    path2 = os.getcwd().replace('\\', '/')
    os.chdir(path1)
    flag = os.path.isfile(filename)
    os.chdir(path2)
    return flag


@app.route('/')
def login_html():
    """
    登录主页
    :return: login.html
    """
    return render_template('login.html')


@app.route('/login', methods=["POST"])
def login():
    global cur_user_local_paths
    global cur_user_id
    if request.method == "POST":
        # 以POST方式传参数，通过form取值
        # 如果Key之不存在，报错KeyError，返回400的页面
        username = request.form['username']
        password = request.form['password']
        user = db.select_user(username)
        if user is None:
            return {"code": 500, "msg": "账号或密码错误"}
        if user.password != password:
            return {"code": 500, "msg": "账号或密码错误"}
        cur_user_local_paths = db.select_sync_path(user.id)
        cur_user_id = user.id
        return {"code": 200, "msg": "登录成功"}


@app.route('/index.html')
def index_html():
    return render_template('index.html')


@app.route('/upload')
def upload_file():
    return render_template('upload.html')


@app.route('/uploader', methods=['GET', 'POST'])
def upload_success():
    if request.method == 'POST':
        f = request.files['file']
        f.save('upload_files/' + f.filename)
        return render_template('upload_success.html', filename=f.filename)


@app.route('/sync_list', methods=['GET'])
def sync_page():
    # 查数据库
    global cur_user_id
    sync_list = db.select_sync_path(user_id=cur_user_id)
    return render_template('sync_page.html', fl=sync_list)


# 显示下载文件的界面
@app.route('/down', methods=['GET'])
def download_page():
    parent_path = '/'
    f_list = get_ftp_files(parent_path=parent_path)
    return render_template('download_page.html', fl=f_list, parent_path=parent_path)


@app.route('/delete_path', methods=['GET'])
def delete_path():
    global cur_user_id
    path_id = request.args.get('pathId')
    print(path_id)
    sync_list = db.select_sync_path(user_id=cur_user_id)
    return render_template('sync_page.html', fl=sync_list)


# 下载要下载的文件，要下载的文件是通过get方法来传递的
@app.route('/download_file', methods=['GET'])
def download_file():
    global cur_user_id
    if request.method == 'GET':

        download_filename = request.args.get('filename')
        # f_list = getfile()
        print("download_filename：" + download_filename)
        download_filepath = ftp_root_path + '/' + 'user-' + str(cur_user_id) + download_filename
        try:
            ftp.cwd(download_filepath)
            # 能进去表示该文件是目录
            f_list = get_ftp_files(parent_path=download_filename)
            return render_template('download_page.html', fl=f_list, parent_path=download_filename + '/')
        except Exception as e:
            b = BytesIO()
            ftp.retrbinary("RETR " + download_filepath, b.write)
            b.seek(0)
            return send_file(b, attachment_filename=os.path.basename(download_filepath))
            # if is_Have_file(download_filename):
            #     return send_from_directory('upload_files', download_filename, as_attachment=True)
        else:
            abort(404)


def my_job():
    global cur_user_id
    global cur_user_local_paths
    print("=====同步开始=====")
    # 获取全部文件
    remote_path = ftp_root_path + '/' + 'user-' + str(cur_user_id)
    if len(cur_user_local_paths) == 0:
        print("用户未登录，停止同步")
        print("=====同步结束=====")
        return
    for local_path in cur_user_local_paths:
        print(f"当前同步的本地目录：【{local_path}】")
        cur_remote_path = remote_path + '/' + 'sync-file-' + str(local_path[0])
        print(f"当前同步到的远程目录{cur_remote_path}")
        scan_upload_files(ftp, str(local_path[1]), remote_path)
    print("=====同步结束=====")


if __name__ == '__main__':
    scheduler.add_job(func=my_job, id='1', trigger='interval', seconds=60)
    scheduler.init_app(app=app)
    scheduler.start()
    app.run(port=5000)
